package cn.demoncat.util.mybatis.plus.base;

import cn.demoncat.util.lang.CollectionUtil;
import cn.demoncat.util.lang.ObjectUtil;
import cn.demoncat.util.lang.entity.MysqlQuery;
import cn.demoncat.util.mybatis.plus.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;

import java.io.Serializable;
import java.util.List;

/**
 * BaseMapper
 *
 * @see <a href="https://gitee.com/baomidou/mybatis-plus-samples/tree/master/mybatis-plus-sample-deluxe">自定义Mapper</a>
 *
 * @author 延晓磊
 * @since 2021年08月31日
 */
public interface BaseMapper<T> extends com.baomidou.mybatisplus.core.mapper.BaseMapper<T> {

    /**
     * 自定义搜索（需要XML支持）
     *
     * @param query 查询参数：字段、条件、分组、排序等，支持子查询
     * @return
     *
     * @author 延晓磊
     * @since 2021年11月25日
     */
    List<T> select(MysqlQuery query);

    /**
     * 批量添加（解决saveBatch循环插入速度慢的问题，需要XML支持）
     *
     * 1、如果赋值ID，使用自定义ID；如果ID为null，使用数据库自增
     * 2、添加后可以通过o.getId()获取主键
     * 3、如果使用INSERT INTO，插入失败时抛异常；如果使用INSERT IGNORE INTO，成功返回1，失败返回0
     *
     * @param os
     * @return 插入的记录数
     *
     * @author 延晓磊
     * @since 2021年11月25日
     */
    int batchSave(List<T> os);

    /**
     * 去重添加 InsertIgnore
     *
     * @param o 如果存在（主键、唯一索引）则忽略，否则添加
     * @return
     *
     * @author 延晓磊
     * @since 2022年02月08日
     */
    int insertIgnore(T o);

    /**
     * 去重添加 ReplaceInto
     *
     * @param o 如果存在（主键、唯一索引）则更新（跨多条数据时合并为1条），否则添加
     * @return
     *
     * @author 延晓磊
     * @since 2022年02月08日
     */
    int replaceInto(T o);

    /**
     * 获取首个
     *
     * @param query 条件+排序
     * @return
     *
     * @author 延晓磊
     * @since 2022年11月04日
     */
    default T getFirst(QueryWrapper<T> query) {
        return CollectionUtil.first(this.selectList(ObjectUtil.toDefault(query, new Query<T>()).last("LIMIT 1")));
    }

    /**
     * ID查询
     *
     * @param id
     * @return
     *
     * @author 延晓磊
     * @since 2022年11月04日
     */
    default T getById(Serializable id){
        return this.selectById(id);
    }

    /**
     * 添加
     *
     * @param entity
     * @return

     * @author 延晓磊
     * @since 2022年11月04日
     */
    default boolean save(T entity){
        return SqlHelper.retBool(this.insert(entity));
    }

    /**
     * 修改
     *
     * @param entity
     * @return

     * @author 延晓磊
     * @since 2022年11月04日
     */
    default boolean update(T entity){
        return SqlHelper.retBool(this.updateById(entity));
    }

    /**
     * 清空
     *
     * @return
     */
    void truncate();
}
